#include <stdio.h>
#include <pthread.h>
#include "Includes/Messaging.h"
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <mqueue.h>
#include <unistd.h>

/// <summary>
/// Locals
/// </summary>
Message msg;
pthread_t m_thread;
pthread_mutex_t m_lock;
struct msqid_ds msg_data;
key_t msg_key_rec = 0x00808000;
key_t msg_key_snd = 0x00808020;
int msg_running = 0;
int msg_id_rec = -1;
int msg_id_snd = -1;

/// <summary>
/// TODO
/// </summary>
int MGSStart(void)
{
	if ((msg_id_rec = msgget(msg_key_rec, IPC_CREAT | 0700)) < 0)
		return -1;

	if ((msg_id_snd = msgget(msg_key_snd, IPC_CREAT | 0700)) < 0)
		return -1;

	if (pthread_create(&m_thread, NULL, MGSRunning, NULL) != 0)
		return -1;

	return 0;
}

/// <summary>
/// TODO
/// </summary>
int inline MSGWait(void)
{
	/* 0x00808000 */
	if (msgrcv(msg_id_rec, &msg, MSG_SIZE, 0, 0) == -1)
		return -1;
	return 0;
}

/// <summary>
/// TODO
/// </summary>
int inline MSGReplay(void)
{
	/* 0x00808020 */
	if (msgsnd(msg_id_snd, &msg, MSG_SIZE, IPC_NOWAIT) == -1)
		return -1;
	return 0;
}

/// <summary>
/// TODO
/// </summary>
int inline MSGGetCount(void)
{
	/* 0x00808000 */
	if (msgctl(msg_id_rec, IPC_STAT, &msg_data) == -1)
		return -1;
	return (int)msg_data.msg_qnum;
}

/// <summary>
/// Posts a message to the
/// message queue of the specified thread.
/// It returns without waiting for the
/// thread to process the message.
/// </summary>
int inline MSGPost(void)
{
	return 0;
}

/// <summary>
/// TODO
/// </summary>
int inline MSGProcess(void)
{
	return 0;
}

/// <summary>
/// TODO
/// </summary>
void* MGSRunning(void* ptr) {

	for (;;) {
		MSGWait();
		MSGProcess();
		MSGReplay();
		//printf("REC: %d\n", (int)msg.pid);
	}
	return NULL;
}

/// <summary>
/// TODO
/// </summary>
int MGSStop(void)
{
	if (pthread_cancel(m_thread) != 0)
		return -1;
	return 0;
}
